﻿/************************************************************************
* Copyright (c) 2019 All Rights Reserved.
*命名空间：BlueFox.Qcloud
*文件名： SmsSendService
*创建人： 覃乃林
*创建时间：2019/2/14 17:31:30
*描述
************************************************************************/
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;

namespace BlueFox.Qcloud
{
    public class SmsSendService
    {

       private Random random = new Random();


        private long GetRandom()
        {
            return random.Next(999999) % 900000 + 100000;
        }

        private long GetCurTime()
        {
            Int32 unixTimestamp = (Int32)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds;
            return unixTimestamp;
        }

        /// <summary>
        /// 普通单发短信接口，明确指定内容，如果有多个签名，请在内容中以【】的方式添加到信息内容中，否则系统将使用默认签名
        /// </summary>
        /// <param name="type">短信类型，0 为普通短信，1 营销短信</param>
        /// <param name="nationCode">国家码，如 86 为中国</param>
        /// <param name="phoneNumber">不带国家码的手机号</param>
        /// <param name="msg">息内容，必须与申请的模板格式一致，否则将返回错误</param>
        /// <param name="extend">扩展码，可填空</param>
        /// <param name="ext">服务端原样返回的参数，可填空</param>
        /// <returns></returns>
        public SmsSingleSenderResult SingleSend(int type,string nationCode,string phoneNumber,string msg,string extend,string ext)
        {
            if (0 != type && 1 != type)
            {
                throw new Exception("type " + type + " error");
            }
            if (null == extend)
            {
                extend = "";
            }
            if (null == ext)
            {
                ext = "";
            }

            long random = GetRandom();
            long curTime = GetCurTime();

            // 按照协议组织 post 请求包体
            JObject data = new JObject();

            JObject tel = new JObject();
            tel.Add("nationcode", nationCode);
            tel.Add("mobile", phoneNumber);

            data.Add("tel", tel);
            data.Add("msg", msg);
            data.Add("type", type);
            data.Add("sig", HttpUtil.StrToHash(String.Format(
                "appkey={0}&random={1}&time={2}&mobile={3}",
                Config.AppKey, random, curTime, phoneNumber)));
            data.Add("time", curTime);
            data.Add("extend", extend);
            data.Add("ext", ext);

            string wholeUrl = Config.SingUrl + "?sdkappid=" + Config.SdkAppid + "&random=" + random;

            var res= HttpUtil.Request(wholeUrl, data);
            SmsSingleSenderResult result;
            if (!string.IsNullOrEmpty(res))
            {
                result = JsonConvert.DeserializeObject<SmsSingleSenderResult>(res) ;
            }
            else
            {
                result = new SmsSingleSenderResult();
                result.result = -1;
                result.errmsg = "http error ";
            }

            return result;
        }

        /// <summary>
        /// 指定模板单发
        /// </summary>
        /// <param name="nationCode">国家码，如 86 为中国</param>
        /// <param name="phoneNumber">不带国家码的手机号</param>
        /// <param name="templId">模板 id</param>
        /// <param name="templParams">模板参数列表，如模板 {1}...{2}...{3}，那么需要带三个参数</param>
        /// <param name="sign">短信签名，如果使用默认签名，该字段可缺省</param>
        /// <param name="extend">扩展码，可填空</param>
        /// <param name="ext">服务端原样返回的参数，可填空</param>
        /// <returns></returns>
        public SmsSingleSenderResult SingleSendWithParam( string nationCode,string phoneNumber,int templId,List<string> templParams,string sign,string extend,string ext)
        {
            if (null == sign)
            {
                sign = "";
            }
            if (null == extend)
            {
                extend = "";
            }
            if (null == ext)
            {
                ext = "";
            }

            long random = GetRandom();
            long curTime = GetCurTime();

            // 按照协议组织 post 请求包体
            JObject data = new JObject();

            JObject tel = new JObject();
            tel.Add("nationcode", nationCode);
            tel.Add("mobile", phoneNumber);

            data.Add("tel", tel);
            data.Add("sig", HttpUtil.CalculateSigForTempl(Config.AppKey, random, curTime, phoneNumber));
            data.Add("tpl_id", templId);
            data.Add("params", HttpUtil.SmsParamsToJSONArray(templParams));
            data.Add("sign", sign);
            data.Add("time", curTime);
            data.Add("extend", extend);
            data.Add("ext", ext);

            string wholeUrl = Config.SingUrl + "?sdkappid=" + Config.SdkAppid + "&random=" + random;

            var res = HttpUtil.Request(wholeUrl, data);
            SmsSingleSenderResult result;
            if (!string.IsNullOrEmpty(res))
            {
                result = JsonConvert.DeserializeObject<SmsSingleSenderResult>(res);
            }
            else
            {
                result = new SmsSingleSenderResult();
                result.result = -1;
                result.errmsg = "http error ";
            }

            return result;
        }

        /// <summary>
        /// 普通群发短信接口，明确指定内容，如果有多个签名，请在内容中以【】的方式添加到信息内容中，否则系统将使用默认签名
        /// 【注意】海外短信无群发功能
        /// </summary>
        /// <param name="type">短信类型，0 为普通短信，1 营销短信</param>
        /// <param name="nationCode">国家码，如 86 为中国</param>
        /// <param name="phoneNumbers">不带国家码的手机号列表</param>
        /// <param name="msg">信息内容，必须与申请的模板格式一致，否则将返回错误</param>
        /// <param name="extend"> 扩展码，可填空</param>
        /// <param name="ext">服务端原样返回的参数，可填空</param>
        /// <returns></returns>
        public SmsMultiSenderResult MultiSend(int type,string nationCode,List<string> phoneNumbers,string msg,string extend,string ext)
        {
            if (0 != type && 1 != type)
            {
                throw new Exception("type " + type + " error");
            }
            if (null == extend)
            {
                extend = "";
            }
            if (null == ext)
            {
                ext = "";
            }

            long random = GetRandom();
            long curTime = GetCurTime();

            // 按照协议组织 post 请求包体
            JObject data = new JObject();
            data.Add("tel", HttpUtil.PhoneNumbersToJSONArray(nationCode, phoneNumbers));
            data.Add("type", type);
            data.Add("msg", msg);
            data.Add("sig", HttpUtil.CalculateSig(Config.AppKey, random, curTime, phoneNumbers));
            data.Add("time", curTime);
            data.Add("extend", extend);
            data.Add("ext", ext);

            string wholeUrl = Config.MultiUrl + "?sdkappid=" + Config.SdkAppid + "&random=" + random;
            var res = HttpUtil.Request(wholeUrl, data);
            SmsMultiSenderResult result;
            if (!string.IsNullOrEmpty(res))
            {
                result = JsonConvert.DeserializeObject<SmsMultiSenderResult>(res);
            }
            else
            {
                result = new SmsMultiSenderResult();
                result.result = -1;
                result.errmsg = "http error ";
            }
            return result;
        }
        /// <summary>
        /// 指定模板群发
        /// 【注意】海外短信无群发功能
        /// </summary>
        /// <param name="nationCode">国家码，如 86 为中国</param>
        /// <param name="phoneNumbers">不带国家码的手机号列表</param>
        /// <param name="templId">模板 id</param>
        /// <param name="templParams">模板参数列表</param>
        /// <param name="sign">签名，如果填空，系统会使用默认签名</param>
        /// <param name="extend">扩展码，可以填空</param>
        /// <param name="ext">服务端原样返回的参数，可以填空</param>
        /// <returns></returns>
        public SmsMultiSenderResult MultiSendWithParam(String nationCode,List<string> phoneNumbers,int templId,List<string> templParams,string sign,string extend,string ext)
        {
            if (null == sign)
            {
                sign = "";
            }
            if (null == extend)
            {
                extend = "";
            }
            if (null == ext)
            {
                ext = "";
            }

            long random = GetRandom();
            long curTime = GetCurTime();

            // 按照协议组织 post 请求包体
            JObject data = new JObject();
            data.Add("tel", HttpUtil.PhoneNumbersToJSONArray(nationCode, phoneNumbers));
            data.Add("sig", HttpUtil.CalculateSigForTempl(Config.AppKey, random, curTime, phoneNumbers));
            data.Add("tpl_id", templId);
            data.Add("params", HttpUtil.SmsParamsToJSONArray(templParams));
            data.Add("sign", sign);
            data.Add("time", curTime);
            data.Add("extend", extend);
            data.Add("ext", ext);

            string wholeUrl = Config.MultiUrl + "?sdkappid=" + Config.SdkAppid + "&random=" + random;
            var res = HttpUtil.Request(wholeUrl, data);
            SmsMultiSenderResult result;
            if (!string.IsNullOrEmpty(res))
            {
                result = JsonConvert.DeserializeObject<SmsMultiSenderResult>(res);
            }
            else
            {
                result = new SmsMultiSenderResult();
                result.result = -1;
                result.errmsg = "http error ";
            }
            return result;
        }

        /// <summary>
        /// 将对象中的属性转为键值对
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <returns></returns>
        public Dictionary<string,string> ObjToHash<T>(T t)
        {
            Dictionary<string, string> hash = new Dictionary<string, string>();
            Type type = typeof(T);
            var p = type.GetProperties();
            foreach (var item in p)
            {
                hash.Add(item.Name.ToLower(), item.GetValue(t)+"");
            }
            return hash;
        }

        /// <summary>
        /// 获取短信模板中的键
        /// </summary>
        /// <param name="Content">"尊敬的{name}客户，您好，您在本店仍有为消费的余额{Balance}"</param>
        /// <returns></returns>
        public Dictionary<string, string> GetHash(string content)
        {
            Dictionary<string, string> hash = new Dictionary<string, string>();
            string pattern = @"\{.*?\}";
            var matches = Regex.Matches(content, pattern, RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture);
            if (matches != null)
            {
                foreach (Match item in matches)
                {
                    hash.Add(item.Value.Replace("{", "").Replace("}", "").ToLower(),"");
                }
            }
            return hash;
        }
    }
}
